# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: site-packages\PyInstaller\utils\hooks\qt.py
import os, sys
from ..hooks import eval_statement, exec_statement, get_homebrew_path
from ... import log as logging
from ...compat import exec_command, is_py3, is_win
from ...utils import misc

logger = logging.getLogger(__name__)


def qt_plugins_dir(namespace):
    """
    Return list of paths searched for plugins.
    
    :param namespace: Import namespace, i.e., PyQt4, PyQt5, PySide, or PySide2
    
    :return: Plugin directory paths
    """
    if namespace not in ("PyQt4", "PyQt5", "PySide", "PySide2"):
        raise Exception(("Invalid namespace: {0}").format(namespace))
    paths = eval_statement(
        (
            "\n        from {0}.QtCore import QCoreApplication;\n        app = QCoreApplication([]);\n        # For Python 2 print would give <PyQt4.QtCore.QStringList\n        # object at 0x....>\", so we need to convert each element separately\n        str = getattr(__builtins__, 'unicode', str);  # for Python 2\n        print([str(p) for p in app.libraryPaths()])\n        "
        ).format(namespace)
    )
    if not paths:
        raise Exception(("Cannot find {0} plugin directories").format(namespace))
    else:
        valid_paths = []
        for path in paths:
            if os.path.isdir(path):
                valid_paths.append(str(path))

        qt_plugin_paths = valid_paths
    if not qt_plugin_paths:
        raise Exception(
            (
                "\n            Cannot find existing {0} plugin directories\n            Paths checked: {1}\n            "
            ).format(namespace, (", ").join(paths))
        )
    return qt_plugin_paths


def qt_plugins_binaries(plugin_type, namespace):
    """
    Return list of dynamic libraries formatted for mod.binaries.
    
    :param plugin_type: Plugin to look for
    :param namespace: Import namespace, i.e., PyQt4, PyQt5, PySide, or PySide2
    
    :return: Plugin directory path corresponding to the given plugin_type
    """
    if namespace not in ("PyQt4", "PyQt5", "PySide", "PySide2"):
        raise Exception(("Invalid namespace: {0}").format(namespace))
    pdir = qt_plugins_dir(namespace=namespace)
    files = []
    for path in pdir:
        files.extend(misc.dlls_in_dir(os.path.join(path, plugin_type)))

    if is_win:
        if namespace in ("PyQt4", "PySide"):
            files = [f for f in files if not f.endswith("d4.dll")]
        if is_win:
            if namespace in ("PyQt5", "PySide2"):
                files = [f for f in files if not f.endswith("d.dll")]
    logger.debug(("Found plugin files {0} for plugin '{1}'").format(files, plugin_type))
    if namespace in ("PyQt4", "PySide"):
        plugin_dir = "qt4_plugins"
    else:
        if namespace == "PyQt5":
            plugin_dir = os.path.join("PyQt5", "Qt", "plugins")
        else:
            plugin_dir = "qt5_plugins"
        dest_dir = os.path.join(plugin_dir, plugin_type)
        binaries = [(f, dest_dir) for f in files]
        return binaries


def qt_menu_nib_dir(namespace):
    """
    Return path to Qt resource dir qt_menu.nib on OSX only.
    
    :param namespace: Import namespace, i.e., PyQt4, PyQt5,  PySide, or PySide2
    
    :return: Directory containing qt_menu.nib for specified namespace
    """
    if namespace not in ("PyQt4", "PyQt5", "PySide", "PySide2"):
        raise Exception(("Invalid namespace: {0}").format(namespace))
    menu_dir = None
    path = exec_statement(
        (
            "\n    from {0}.QtCore import QLibraryInfo\n    path = QLibraryInfo.location(QLibraryInfo.LibrariesPath)\n    str = getattr(__builtins__, 'unicode', str)  # for Python 2\n    print(str(path))\n    "
        ).format(namespace)
    )
    anaconda_path = os.path.join(sys.exec_prefix, "python.app", "Contents", "Resources")
    paths = [
        os.path.join(path, "Resources"),
        os.path.join(path, "QtGui.framework", "Resources"),
        anaconda_path,
    ]
    for location in paths:
        path = os.path.join(location, "qt_menu.nib")
        if os.path.exists(path):
            menu_dir = path
            logger.debug(("Found qt_menu.nib for {0} at {1}").format(namespace, path))
            break

    if not menu_dir:
        raise Exception(
            (
                "\n            Cannot find qt_menu.nib for {0}\n            Path checked: {1}\n            "
            ).format(namespace, (", ").join(paths))
        )
    return menu_dir


def get_qmake_path(version=""):
    """
    Try to find the path to qmake with version given by the argument as a string.
    
    :param version: qmake version
    """
    import subprocess

    if "QT5DIR" in os.environ:
        if version[0] == "5":
            logger.debug("Using $QT5DIR/bin as qmake path")
            return os.path.join(os.environ["QT5DIR"], "bin", "qmake")
        if "QT4DIR" in os.environ:
            if version[0] == "4":
                logger.debug("Using $QT4DIR/bin as qmake path")
                return os.path.join(os.environ["QT4DIR"], "bin", "qmake")
            dirs = [""]
            for formula in ("qt", "qt5"):
                homebrewqtpath = get_homebrew_path(formula)
                if homebrewqtpath:
                    dirs.append(homebrewqtpath)

            for directory in dirs:
                try:
                    qmake = os.path.join(directory, "bin", "qmake")
                    versionstring = subprocess.check_output(
                        [qmake, "-query", "QT_VERSION"]
                    ).strip()
                    if is_py3:
                        versionstring = versionstring.decode("utf8")
                    if versionstring.find(version) == 0:
                        logger.debug(
                            'Found qmake version "%s" at "%s".' % (versionstring, qmake)
                        )
                        return qmake
                except (OSError, subprocess.CalledProcessError):
                    pass

            logger.debug('Could not find qmake matching version "%s".' % version)


def qt5_qml_dir(namespace):
    if namespace not in ("PyQt5", "PySide2"):
        raise Exception(("Invalid namespace: {0}").format(namespace))
    if namespace == "PyQt5":
        import PyQt5

        qmldir = os.path.join(PyQt5.__path__[0], "Qt", "qml")
        if os.path.isdir(qmldir):
            return qmldir
        qmake = get_qmake_path("5")
        if qmake is None:
            qmldir = ""
            logger.error(
                "Could not find qmake version 5.x, make sure PATH is set correctly or try setting QT5DIR."
            )
        else:
            qmldir = exec_command(qmake, "-query", "QT_INSTALL_QML").strip()
        if len(qmldir) == 0:
            logger.error(
                'Cannot find QT_INSTALL_QML directory, "qmake -query '
                + 'QT_INSTALL_QML" returned nothing'
            )
        else:
            if not os.path.exists(qmldir):
                logger.error("Directory QT_INSTALL_QML: %s doesn't exist" % qmldir)
        qmldir = os.path.normpath(qmldir)
        return qmldir


def qt5_qml_data(qmldir, directory):
    """
    Return Qml library directory formatted for data.
    """
    return (os.path.join(qmldir, directory), os.path.join("qml", directory))


def qt5_qml_plugins_binaries(qmldir, directory):
    """
    Return list of dynamic libraries formatted for mod.binaries.
    """
    binaries = []
    qt5_qml_plugin_dir = os.path.join(qmldir, directory)
    files = misc.dlls_in_subdirs(qt5_qml_plugin_dir)
    for f in files:
        relpath = os.path.relpath(f, qmldir)
        instdir, file = os.path.split(relpath)
        instdir = os.path.join("qml", instdir)
        logger.debug("qt5_qml_plugins_binaries installing %s in %s" % (f, instdir))
        binaries.append((f, instdir))

    return binaries


def qt5_qml_plugins_datas(qmldir, directory):
    """
    Return list of data files for mod.binaries. (qmldir, *.qmltypes)
    """
    datas = []
    qt5_qml_plugin_dir = os.path.join(qmldir, directory)
    files = []
    for root, _dirs, _files in os.walk(qt5_qml_plugin_dir):
        files.extend(misc.files_in_dir(root, ["qmldir", "*.qmltypes"]))

    for f in files:
        relpath = os.path.relpath(f, qmldir)
        instdir, file = os.path.split(relpath)
        instdir = os.path.join("qml", instdir)
        logger.debug("qt5_qml_plugins_datas installing %s in %s" % (f, instdir))
        datas.append((f, instdir))

    return datas


__all__ = (
    "qt_plugins_dir",
    "qt_plugins_binaries",
    "qt_menu_nib_dir",
    "get_qmake_path",
    "qt5_qml_dir",
    "qt5_qml_data",
    "qt5_qml_plugins_binaries",
    "qt5_qml_plugins_datas",
)
